package utils;

import entity.rtsp.RTSPRequestEntity;
import entity.rtsp.RTSPResponseEntity;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class RTSPPacketParser {
    private static RTSPPacketParser instance;
    private static final int bufferSize = 10000;
    private static String lineSeparator = "\r\n";

    public static RTSPPacketParser getInstance(){
        if(instance == null){
            synchronized (RTSPPacketParser.class){
                if(instance == null){
                    instance = new RTSPPacketParser();
                }
            }
        }

        return instance;
    }


    public RTSPRequestEntity requestEntityParser(InputStream in) throws IOException {
        String headerStr = readHeaderString(in);

        if(StringUtils.isEmpty(headerStr)){
            return null;
        }

        //取第一行作为target
        String target = headerStr.substring(0, headerStr.indexOf(lineSeparator));
        String method = target.substring(0, target.indexOf(" "));
        String targetUri = target.substring(target.indexOf(" ") + 1, target.lastIndexOf(" "));
        String version = target.substring(target.lastIndexOf(" ") + 1);
        //剩余的解析为headers
        headerStr = headerStr.substring(headerStr.indexOf(lineSeparator) + 2);
        Map<String, String> headers = parseHeaderString(headerStr);

        RTSPRequestEntity rtspRequestEntity = new RTSPRequestEntity();
        rtspRequestEntity.setMethod(method);
        rtspRequestEntity.setTargetUri(targetUri);
        rtspRequestEntity.setVersion(version);
        rtspRequestEntity.setHeaders(headers);

        return rtspRequestEntity;
    }


    public RTSPResponseEntity responseEntityParser(InputStream in) throws IOException {
        String headerStr = readHeaderString(in);

        if(StringUtils.isEmpty(headerStr)){
            return null;
        }

        String target = headerStr.substring(0, headerStr.indexOf(lineSeparator));
        String version = target.substring(0, target.indexOf(" "));
        String statucCode = target.substring(target.indexOf(" ") + 1, target.lastIndexOf(" "));
        String word = target.substring(target.lastIndexOf(" ") + 1);

        headerStr = headerStr.substring(headerStr.indexOf(lineSeparator) + 2);
        Map<String, String> headers = parseHeaderString(headerStr);

        String body = null;
        if(headers.containsKey("Content-Length")){
            int length = Integer.parseInt(headers.get("Content-Length"));
            byte[] buffer = new byte[length];
            int bytesRead = in.read(buffer, 0, length);
            body = new String(buffer, 0, bytesRead);
        }

        RTSPResponseEntity rtspResponseEntity = new RTSPResponseEntity();
        rtspResponseEntity.setVersion(version);
        rtspResponseEntity.setStatusCode(statucCode);
        rtspResponseEntity.setWord(word);
        rtspResponseEntity.setHeaders(headers);
        rtspResponseEntity.setBody(body);

        return rtspResponseEntity;
    }


    private String readHeaderString(InputStream in) throws IOException {
        int separatorCount = 0;
        byte[] buffer = new byte[bufferSize];
        int bytesRead = 0;
        int tmp = -2;
        String result = "";

        while(bytesRead < bufferSize && (tmp = in.read()) != -1){

            buffer[bytesRead++] = (byte)tmp;

            //当连续读取到4个\r或\n，说明已经读到header的最后了，否则重置计数器
            if(tmp == '\r' || tmp == '\n'){
                separatorCount++;
            }else{
                separatorCount = 0;
            }

            if(separatorCount == 4){
                break;
            }
        }

        result = new String(buffer, 0, bytesRead, "UTF-8");

        return result;
    }

    private Map<String, String> parseHeaderString(String headerString){
        String currentLine = "";
        Map<String, String> headers = new HashMap<>();

        while(true){
            currentLine = headerString.substring(0, headerString.indexOf(lineSeparator));

            //已解析到最后的两个\r\n处，退出循环
            if("".equals(currentLine)){
                break;
            }

            headers.put(
                    currentLine.substring(0, currentLine.indexOf(':')),
                    currentLine.substring(currentLine.indexOf(':') + 2, currentLine.length())
            );
            headerString = headerString.substring(headerString.indexOf(lineSeparator) + 2);
        }

        return headers;
    }
}
